package chpn.id.util;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 定时任务工具类
 * 提供创建、管理和取消定时任务的功能
 */
public class TimerUtil {
    // 定时任务执行器
    private static final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(
        Runtime.getRuntime().availableProcessors(),
        new ThreadFactory() {
            private final AtomicInteger threadNumber = new AtomicInteger(1);
            
            @Override
            public Thread newThread(Runnable r) {
                Thread thread = new Thread(r, "timer-util-" + threadNumber.getAndIncrement());
                thread.setDaemon(true); // 设置为守护线程，不阻止JVM退出
                return thread;
            }
        }
    );
    
    // 存储任务ID和对应的ScheduledFuture，用于取消任务
    private static final Map<String, ScheduledFuture<?>> taskMap = new ConcurrentHashMap<>();
    
    /**
     * 创建一个固定频率执行的定时任务
     * 
     * @param taskId 任务ID，用于后续取消任务
     * @param task 要执行的任务
     * @param initialDelay 初始延迟时间
     * @param period 任务执行的时间间隔
     * @param unit 时间单位
     * @return 任务ID
     */
    public static String scheduleAtFixedRate(String taskId, Runnable task, long initialDelay, long period, TimeUnit unit) {
        ScheduledFuture<?> future = scheduler.scheduleAtFixedRate(task, initialDelay, period, unit);
        taskMap.put(taskId, future);
        return taskId;
    }
    
    /**
     * 创建一个固定延迟执行的定时任务
     * 
     * @param taskId 任务ID，用于后续取消任务
     * @param task 要执行的任务
     * @param initialDelay 初始延迟时间
     * @param delay 任务执行完成后到下一次执行的延迟时间
     * @param unit 时间单位
     * @return 任务ID
     */
    public static String scheduleWithFixedDelay(String taskId, Runnable task, long initialDelay, long delay, TimeUnit unit) {
        ScheduledFuture<?> future = scheduler.scheduleWithFixedDelay(task, initialDelay, delay, unit);
        taskMap.put(taskId, future);
        return taskId;
    }
    
    /**
     * 创建一个只执行一次的定时任务
     * 
     * @param taskId 任务ID，用于后续取消任务
     * @param task 要执行的任务
     * @param delay 延迟时间
     * @param unit 时间单位
     * @return 任务ID
     */
    public static String schedule(String taskId, Runnable task, long delay, TimeUnit unit) {
        ScheduledFuture<?> future = scheduler.schedule(task, delay, unit);
        taskMap.put(taskId, future);
        return taskId;
    }
    
    /**
     * 取消指定ID的任务
     * 
     * @param taskId 任务ID
     * @param mayInterruptIfRunning 是否中断正在执行的任务
     * @return 是否成功取消
     */
    public static boolean cancelTask(String taskId, boolean mayInterruptIfRunning) {
        ScheduledFuture<?> future = taskMap.remove(taskId);
        if (future != null) {
            return future.cancel(mayInterruptIfRunning);
        }
        return false;
    }
    
    /**
     * 关闭定时任务执行器
     * 在应用程序关闭时调用，释放资源
     */
    public static void shutdown() {
        // 取消所有任务
        for (ScheduledFuture<?> future : taskMap.values()) {
            future.cancel(true);
        }
        taskMap.clear();
        
        // 关闭执行器
        scheduler.shutdownNow();
        try {
            // 等待执行器关闭，最多等待5秒
            scheduler.awaitTermination(5, TimeUnit.SECONDS);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
    
    /**
     * 检查任务是否存在
     * 
     * @param taskId 任务ID
     * @return 任务是否存在
     */
    public static boolean taskExists(String taskId) {
        return taskMap.containsKey(taskId);
    }
    
    /**
     * 获取当前任务数量
     * 
     * @return 任务数量
     */
    public static int getTaskCount() {
        return taskMap.size();
    }
}